﻿/**
 * @brief     自定义Log日志
 * @details   基于Qt架构做的 日志模块
 * @author    Yin
 * @version   1.0
 * @date
 * @copyright
 * @note
 *  另外实现功能：单个日志文件例如大于 5M 后重新创建一个新的日志文件；删除超过 30 天的日志；使用锁确保多线程安全。
 *  后期考虑实现功能： 日志的相关配置数据例如输出目录写到配置文件； 日志可以选择存放在服务器。
 *  Release 版本默认不包含文件名、函数名和行数信息，需要在 .pro 文件中加入一行代码，重新 make 运行后生效。 需添加： DEFINES += QT_MESSAGELOGCONTEXT
DEMO 使用方式

#include "system/qtloghandler.h"
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    // [1] 安装消息处理函数
    Common::QtLogHandler::Get().installMessageHandler();

    OfMainWindow w;
    w.show();

    qDebug() << "当前时间是: " << QTime::currentTime().toString("hh:mm:ss");
    qInfo() << QString("God bless you!");
	qWarning() << QString("God bless you!");
	qCritical() << QString("God bless you!");
	qFatal() << QString("God bless you!");

    // [4] 程序结束时释放 LogHandler 的资源，例如刷新并关闭日志文件
    // TODO 配合主程序使用时，在析构函数中释放
    Common::QtLogHandler::Get().uninstallMessageHandler();
    return a.exec();
}
 */

#ifndef QTLOGHANDLER_H
#define QTLOGHANDLER_H

#include "common_global.h"

#include <QObject>
#include <iostream>
#include <QDebug>
#include <QDateTime>
#include <QMutexLocker>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QTimer>
#include <QTextStream>
#include <QTextCodec>

namespace Common {

	const int g_logLimitSize = 5;               // 日志文件最大值

	class LogHandlerPrivate
	{
	public:
		LogHandlerPrivate();
		~LogHandlerPrivate();

	public:
		/**
		 * @brief openAndBackupLogFile 打开日志文件 log.txt，如果日志文件不是当天创建的，则使用创建日期把其重命名为 yyyy-MM-dd.log，并重新创建一个 log.txt
		 */
		void openAndBackupLogFile();

		/**
		 * @brief checkLogFiles 检测当前日志文件大小
		 */
		void checkLogFiles();

		/**
		 * @brief autoDeleteLog 自动删除30天前的日志
		 */
		void autoDeleteLog();

		/**
		 * @brief messageHandler 消息处理函数
		 * @param type
		 * @param context
		 * @param msg
		 */
		static void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);

	public:
		QDir   m_logDir;                      // 日志文件夹
		QTimer m_renameLogFileTimer;          // 重命名日志文件使用的定时器
		QTimer flushLogFileTimer;           // 刷新输出到日志文件的定时器
		QDate  logFileCreatedDate;          // 日志文件创建的时间

		static QFile *logFile;              // 日志文件
		static QTextStream *logOut;         // 输出日志的 QTextStream，使用静态对象就是为了减少函数调用的开销
		static QMutex logMutex;             // 同步使用的 mutex
	};

	class COMMONSHARED_EXPORT QtLogHandler : public QObject
	{
		Q_OBJECT

	public:
		static QtLogHandler& Get()
		{
			static QtLogHandler m_logHandler;
			return m_logHandler;
		}

		/**
		 * @brief installMessageHandler 给Qt安装消息处理函数
		 */
		void installMessageHandler();

		/**
		 * @brief uninstallMessageHandler 取消安装消息处理函数并释放资源
		 */
		void uninstallMessageHandler();

	private:
		QtLogHandler();

		LogHandlerPrivate * d;
	};

}//namespace Common

#endif // QTLOGHANDLER_H
